package com.yycx.app.provider.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.utils.SpringContextHolder;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.constants.SettingConstant;
import com.yycx.common.enums.SmsCodeTypeEnum;
import com.yycx.common.base.handler.SmsSendHandler;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.utils.*;
import com.yycx.module.user.client.entity.AppAccount;
import com.yycx.module.user.client.entity.SysSlider;
import com.yycx.module.user.provider.service.AppAccountService;
import com.yycx.module.user.provider.service.SysHtmlService;
import com.yycx.module.user.provider.service.SysSliderService;
import com.yycx.common.utils.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yycx.common.constants.CommonConstants.*;
import static com.yycx.common.enums.SmsCodeTypeEnum.REG;
import static com.yycx.common.enums.SmsCodeTypeEnum.UPDATE;

/**
 * @author: zyf
 * @date: 2018/11/9 15:43
 * @description: 通用模块接口, 不需要登录鉴权的接口
 */
@Api(tags = "公共服务")
@RestController
@RequestMapping("/common")
public class AppCommonController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysSliderService sysSliderService;

    @Autowired
    private AppAccountService appAccountService;

    @Autowired
    private SysHtmlService htmlService;


    /**
     * 获取验证码
     *
     * @param useType 1:注册、换绑手机号,2:找回密码,3绑定手机号
     * @param mobile
     * @return
     */
    @ApiOperation(value = "获取验证码", notes = "useType说明:REG用于注册、绑定新手机号,UPDATE用户忘记密码,修改密码")
    @PostMapping("/getSmsCode")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", required = true, value = "手机号", paramType = "form", defaultValue = "tf4E9/6ZWDVBmn+LHhAMDg=="),
            @ApiImplicitParam(name = "areaCode", value = "区号(默认+86,并进行手机号合法检测)", paramType = "form"),
            @ApiImplicitParam(name = "accountType", value = "账户类型(绑定手机号使用)", paramType = "form"),
            @ApiImplicitParam(name = "useType", required = true, value = "验证码用途", paramType = "form")
    })
    public ResultBody getSmsCode(SmsCodeTypeEnum useType, String mobile, @RequestParam(value = "areaCode", defaultValue = "+86", required = false) String areaCode, @RequestParam(value = "accountType", required = false) String accountType) {
        EntityMap map = redisUtils.getConfigMap("SMS_CONFIG");
        Boolean encryption = MapUtil.getBool(map, SettingConstant.SMS_ENCRYPTION, false);
        String tel = mobile;
        if (FlymeUtils.isNotEmpty(encryption) && encryption) {
            String encryptionMode = MapUtil.getStr(map, SettingConstant.SMS_ENCRYPTION_MODE, "AES");
            //解密手机号
            if (encryptionMode.equals("AES")) {
                tel = AesUtil.decryptByHex(mobile);
            } else {
                tel = Des3Util.decode(mobile);
            }
        }
        ApiAssert.isTrue("手机号非法", StringUtils.isPhoneLegal(tel, areaCode));
        ApiAssert.isNotEmpty("验证码用途不能为空", useType);
        if (!CommonConstants.SMS_USETYPE_BIND.equals(useType.getCode())) {
            //手机号是否已注册
            Boolean tag = appAccountService.checkByAccountName(tel);
            if (SMS_USETYPE_REG.equals(useType.getCode()) || REG.equals(useType)) {
                if (tag) {
                    return ResultBody.failed("手机号已注册");
                }
            }
            if (SMS_USETYPE_UPDATE.equals(useType.getCode()) || UPDATE.equals(useType)) {
                if (!tag) {
                    return ResultBody.failed("账号不存在");
                }
            }
        } else {
            //绑定手机号逻辑
            AppAccount account = appAccountService.getMobileAccount(tel);
            if (FlymeUtils.isNotEmpty(account)) {
                Long userId = account.getUserId();
                if (FlymeUtils.isNotEmpty(userId)) {
                    Boolean check = appAccountService.isExist(userId, accountType);
                    if (check) {
                        return ResultBody.failed("该账号已绑定");
                    }
                }
            }
        }
        Integer code = RandomUtil.randomInt(100000, 999999);
        //保存验证码
        redisUtils.set(CommonConstants.PRE_SMS + tel, code, 900);
        Boolean enable = map.get(SettingConstant.OPEN_SMS, false);
        Map<String, Integer> params = new HashMap<>(3);
        params.put("code", code);
        if (enable) {
            //自定义短信处理器
            String handlerName = MapUtil.getStr(map, SettingConstant.SMS_CODE_HANDLE, "");
            //发送验证码
            SmsSendHandler smsSendHandler = SpringContextHolder.getHandler(handlerName, SmsSendHandler.class);
            if (FlymeUtils.isNotEmpty(smsSendHandler)) {
                smsSendHandler.send(tel, code, areaCode);
                return ResultBody.msg("发送成功");
            } else {
                return ResultBody.failed("请设置短信发送处理器");
            }
        } else {
            return ResultBody.ok("发送成功", params);
        }
    }


    /**
     * 获取加密手机号
     *
     * @param mobile
     * @return
     */
    @ApiOperation(value = "加密手机号", notes = "获取加密手机号")
    @PostMapping("/getMobile")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", required = true, value = "手机号", paramType = "form")
    })
    public ResultBody getMobile(String mobile) {
        String key1 = Des3Util.encode(mobile);
        return ResultBody.ok("获取成功", key1);
    }

    /**
     * 修改密码
     */
    @ApiOperation(value = "修改密码(验证码)", notes = "根据验证码修改密码")
    @PostMapping("resetPwdBySmsCode")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "smsCode", required = true, value = "验证码", paramType = "form"),
            @ApiImplicitParam(name = "mobile", required = true, value = "手机号", paramType = "form", defaultValue = "18739941307"),
            @ApiImplicitParam(name = "newPassword", required = true, value = "新密码", paramType = "form")
    })
    public ResultBody resetPwdBySmsCode(@RequestParam(value = "mobile") String mobile,
                                        @RequestParam(value = "smsCode") String smsCode,
                                        @RequestParam(value = "newPassword") String newPassword
    ) {
        appAccountService.resetPwdBySmsCode(mobile, smsCode, newPassword);
        return ResultBody.msg("修改成功");
    }


    /**
     * 抓取网址标题和logo
     */
    @ApiOperation(value = "抓取网址标题和logo", notes = "抓取网址标题和logo")
    @GetMapping("/findTitleAndIco")
    public ResultBody findTitleAndIco(@RequestParam String url) {
        JSONObject result = HtmlUtils.findTitleAndIco(url);
        return ResultBody.ok(result);
    }


    /**
     * 根据类型查询轮播图
     *
     * @param sliderType
     * @return
     */
    @ApiOperation(value = "根据类型查询轮播图", notes = "根据类型查询轮播图")
    @GetMapping("/listSliderByType")
    public ResultBody sliderType(@RequestParam Integer sliderType) {
        ApiAssert.isNotEmpty("轮播图类型不能为空", sliderType);
        List<EntityMap> sliderList = sysSliderService.listSliderByType(sliderType);
        return ResultBody.ok(sliderList);
    }

    /**
     * 根据ID查询轮播图
     *
     * @param sliderId
     * @return
     */
    @ApiOperation(value = "根据ID查询轮播图", notes = "根据ID查询轮播图")
    @GetMapping("/findSliderById")
    public ResultBody listSliderByType(@RequestParam Long sliderId) {
        SysSlider slider=sysSliderService.getById(sliderId);
        return ResultBody.ok(slider);
    }


    /**
     * 生成登录二维码
     *
     * @return
     */
    @ApiOperation(value = "生成登录二维码", notes = "生成登录二维码")
    @GetMapping("/getLoginQrcode")
    public ResultBody getLoginQrcode() {
        String qrcodeId = IdWorker.getIdStr();
        //定义二维码参数
        EntityMap params = new EntityMap();
        params.put("qrcodeId", qrcodeId);
        String qrcode = QRCodeUtils.createQRCodeByBase64(JSONObject.toJSONString(params));
        //存放二维码唯一标识30秒有效
        redisUtils.set(SettingConstant.LOGIN_QRCODE + qrcodeId, qrcodeId, 30);
        EntityMap result = new EntityMap();
        result.put("qrcode", qrcode);
        result.put("qrcodeId", qrcodeId);
        return ResultBody.ok(result);
    }

    /**
     * 扫码二维码
     *
     * @param qrcodeId
     * @param token
     * @return
     */
    @ApiOperation(value = "扫码登录二维码", notes = "扫码登录二维码")
    @PostMapping("/scanLoginQrcode")
    public ResultBody scanLoginQrcode(@RequestParam String qrcodeId, @RequestParam String token) {
        ApiAssert.isNotEmpty("qrcodeId参数不能为空", qrcodeId);
        ApiAssert.isNotEmpty("token参数不能为空", token);
        String check = redisUtils.getString(SettingConstant.LOGIN_QRCODE + qrcodeId);
        if (FlymeUtils.isNotEmpty(check)) {
            //存放token给前台读取
            redisUtils.set(SettingConstant.LOGIN_QRCODE_TOKEN + qrcodeId, token, 60);
        } else {
            return ResultBody.failed("二维码已过期,请刷新后重试");
        }
        return ResultBody.ok("扫码成功");
    }


    /**
     * 获取用户扫码后保存的token
     *
     * @param qrcodeId
     * @return
     */
    @ApiOperation(value = "获取用户扫码后保存的token", notes = "获取用户扫码后保存的token")
    @GetMapping("/getQrcodeToken")
    public ResultBody getQrcodeToken(@RequestParam String qrcodeId) {
        ApiAssert.isNotEmpty("qrcodeId参数不能为空", qrcodeId);
        String token = redisUtils.getString(SettingConstant.LOGIN_QRCODE_TOKEN + qrcodeId);
        EntityMap result = new EntityMap();
        String qrcodeIdExpire = redisUtils.getString(SettingConstant.LOGIN_QRCODE + qrcodeId);
        if (FlymeUtils.isEmpty(qrcodeIdExpire)) {
            //二维码过期通知前台刷新
            result.put("token", "-2");
            return ResultBody.ok(result);
        }
        if (FlymeUtils.isNotEmpty(token)) {
            result.put("success", true);
            result.put("token", token);
        } else {
            result.put("token", "-1");
        }
        return ResultBody.ok(result);
    }
    @ApiOperation(value = "根据htmlCode查询协议", notes = "根据htmlCode查询协议")
    @GetMapping(value = "/findByCode")
    public ResultBody findByCode(String htmlCode,Boolean hasChild) {
        EntityMap map = new EntityMap();
        if(FlymeUtils.isNotEmpty(hasChild)){
            map=htmlService.findByHtmlCode(htmlCode,hasChild);
        }else{
            map=htmlService.findByHtmlCode(htmlCode);
        }
        return ResultBody.ok(map);
    }
}
